﻿namespace Resonator.Core.Services
{
	using System.Collections.Generic;
	using System.Diagnostics;
	using System.Globalization;
	using Resonator.Domain.Models;
	using Resonator.Domain.Services;

	public class ResourceMerger : IResourceMerger
	{
		#region IResourceMerger Members

		public virtual IList<Resource> Merge(IEnumerable<Resource> resources)
		{
			return Merge( resources, CultureInfo.InvariantCulture );
		}

		public virtual IList<Resource> Merge(IEnumerable<Resource> resources, CultureInfo defaultCulture)
		{
			Dictionary<string, Resource> mergedResources = new Dictionary<string, Resource>();

			foreach( Resource resource in resources )
			{
				Resource existingResource;
				if( !mergedResources.TryGetValue( resource.Name, out existingResource ) )
				{
					if( resource.Culture == defaultCulture )
					{
						mergedResources.Add( resource.Name, resource );
						continue;
					}
					else
					{
						Resource placeHolder = new Resource();
						placeHolder.Id = -1;
						placeHolder.Name = resource.Name;
						placeHolder.Culture = defaultCulture;
						placeHolder.AddTranslation( Translation.FromResource( resource ) );
						mergedResources.Add( placeHolder.Name, placeHolder );
						continue;
					}
				}

				if( existingResource.Culture != resource.Culture )
				{
					Translation existingTranslation = existingResource.FindTranslation( resource.Culture );
					if( existingTranslation == null )
					{
						existingResource.AddTranslation( Translation.FromResource( resource ) );
					}
					else
					{
						throw new ResonatorException("Duplicate translation found.  Resource.Phrase='{0}', Translation.Phrase='{1}', Translation.Culture='{2}'", existingResource.Phrase, existingTranslation.Phrase, existingTranslation.Culture);
					}
				}
				// Place holder
				else if( existingResource.Id == -1 )
				{
					existingResource.Id = 0;
					existingResource.CopyFrom( resource );
				}
				else
				{
					throw new ResonatorException("Duplicate resource found.  Resource.Phrase='{0}'", existingResource.Phrase);
				}
			}

			List<Resource> resourceList = new List<Resource>( mergedResources.Values );

			resourceList.ForEach( delegate(Resource r) { r.Id = 0; } );

			return resourceList;
		}

		#endregion
	}
}